#include "Function.h"
#include "Identifier.h"
#include "Type.h"
#include "Pattern.h"

using namespace moses;


FunctionRow::FunctionRow(Identifier *pIdentifier,
	ItemList<Pattern> *pPatternList, Expr *pExpr)

:	m_pIdentifier(pIdentifier),
	m_pPatternList(pPatternList),
	m_pExpr(pExpr)
{
}

bool FunctionRow::MatchesArgs(Runtime *pEnv, ItemList<Expr> *pArgs)
{
	for (size_t i = 0; i < m_pPatternList->size(); i++)
	{
		Pattern *p = (*m_pPatternList)[i];
		
		if (!p->Match(pEnv, (*pArgs)[i]))
			return false;
	}
	return true;
}

Identifier* FunctionRow::GetIdentifier()
{
	return m_pIdentifier;
}

ItemList<Pattern>* FunctionRow::GetPatternList()
{
	return m_pPatternList;
}
		
Expr* FunctionRow::GetExpr()
{
	return m_pExpr;
}
		

/////////////////////////////////////////////////////////////////////////////	

Function::Function(Identifier *pIdentifier, ItemList<Type> *pParams,
	ItemList<FunctionRow> *pRows)
	
:	m_pIdentifier(pIdentifier),
	m_pParams(pParams),
	m_pRows(pRows)
{
}

Identifier* Function::GetIdentifier()
{
	return m_pIdentifier;
}

ItemList<Type>* Function::GetParameters()
{
	return m_pParams;
}

ItemList<FunctionRow>* Function::GetRows()
{
	return m_pRows;
}

Value Function::Call(Runtime *pEnv, ItemList<Expr> *pArgs)
{
	for (size_t i = 0; i < m_pRows->size(); i++)
	{
		FunctionRow *pRow = (*m_pRows)[i];
		
		if (pRow->MatchesArgs(pEnv, pArgs))
			return pRow->GetExpr()->Evaluate(pEnv);
	}
	
	return Value(__FILE__ ": No pattern match");
}

